#include "cynFsm.h"

#ifndef STATEMACHINE_USE_MIN
void cynFsmTick(cynFsmClass *fobj,mu32 ms)
{
    fobj->delay_cnt += ms;
}
#endif

void cynFsmObjInit(cynFsmClass *fobj,mu32 stanum)
{
    memset(fobj,0,sizeof(fobj));
    fobj->stateNum = stanum;
    fobj->currentStatus = fobj->nextStatus = fobj->stateNum + 1;
}

void cynFsmRun(cynFsmClass *fobj)
{
    if(fobj->currentStatus != fobj->nextStatus)
    {
    #ifndef STATEMACHINE_USE_MIN
        if(fobj->delay_cnt >= fobj->delay)
        {
    #endif    
            if(fobj->currentStatus < fobj->stateNum)
            {
                if(fobj->stateProcess[fobj->currentStatus].exit)
                {
                #ifndef STATEMACHINE_USE_MIN
                    fobj->stateProcess[fobj->currentStatus].exit(fobj->funArg);
                #else
                    fobj->stateProcess[fobj->currentStatus].exit(0);
                #endif
                }
            }
            fobj->currentStatus = fobj->nextStatus;
            if(fobj->stateProcess[fobj->currentStatus].entry)
            {
            #ifndef STATEMACHINE_USE_MIN
                fobj->stateProcess[fobj->currentStatus].entry(fobj->funArg);
            #else
                fobj->stateProcess[fobj->currentStatus].entry(0);
            #endif
            }
    #ifndef STATEMACHINE_USE_MIN
        }
    #endif  
    }
    else
    {
        if(fobj->stateNum > fobj->currentStatus)
        {
            if(fobj->stateProcess[fobj->currentStatus].process)
            {
            #ifndef STATEMACHINE_USE_MIN
                fobj->funReturn = fobj->stateProcess[fobj->currentStatus].process(fobj->funArg);
            #else
                fobj->stateProcess[fobj->currentStatus].process(0);
            #endif
            }
        }
    }
}


void cynFsmRegister(cynFsmClass *fobj,mu8 stanum,cynStateMachineFunc entry,cynStateMachineFunc process,cynStateMachineFunc exit)
{
    if(fobj->stateNum > stanum)
    {
        fobj->stateProcess[stanum].entry = entry;
        fobj->stateProcess[stanum].process = process;
        fobj->stateProcess[stanum].exit = exit;
    }
}

void cynFsmUnregister(cynFsmClass *fobj,mu8 stanum)
{
    if(fobj->stateNum > stanum)
    {
        memset(&(fobj->stateProcess[stanum]),0,sizeof(cynFsmFuncs));
    }
}

void cynFsmJump(cynFsmClass *fobj,mu8 next,mu32 delay)
{
    if(fobj->stateNum > next)
    {
        #ifndef STATEMACHINE_USE_MIN
        fobj->delay = delay;
        fobj->delay_cnt = 0;
        #else
        (void)(delay);
        #endif
        fobj->nextStatus = next;
    }
}

#ifndef STATEMACHINE_USE_MIN
void cynFsmObjSetArg(cynFsmClass *fobj,mu32 arg)
{
    if(fobj)
    {
        fobj->funArg = arg;
    }
}
#endif

#ifndef STATEMACHINE_USE_MIN
mu32 cynFsmObjGetRes(cynFsmClass *fobj)
{
    if(fobj)
    {
        return fobj->funReturn;
    }
    return 0xffffffff;
}
#endif

mu8 cynFsmObjGetStatus(cynFsmClass *fobj)
{
    if(fobj)
    {
        return fobj->currentStatus;
    }
    return 0xff;
}

/*
//    sample




*/